﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Domain.Entities;
using Domain.Enums;
using Domain.UnitOfWork;
using Mestedur.Models;
using Mestedur.Models.Membership;
using Services;

namespace Mestedur.Controllers
{
    public class TestController : Controller
    {
        //
        // GET: /Test/
        readonly IResultService resultService;
        readonly IQuizService quizService;
        readonly IUserService userService;
        readonly IUnitOfWorkFactory unitOfWorkFactory;
        readonly IDatabaseService databaseService;

        public TestController(IUnitOfWorkFactory unitOfWorkFactory, IResultService resultService, IQuizService quizService, IFormAuthenticationService formsService, IUserService userService, IDatabaseService databaseService)
        {
            this.resultService = resultService;
            this.databaseService = databaseService;
            this.quizService = quizService;
            this.userService = userService;
            this.unitOfWorkFactory = unitOfWorkFactory;
        }

        [Authorize]
        public ActionResult GetTest(int chapterId)
        {
            using (var unit = unitOfWorkFactory.Create())
            {
                var chapter = databaseService.Chapters.Get(chapterId);
                if (chapter == null)
                {
                    return null;
                }
                ViewData["ChapterId"] = chapter.Id;
                ViewData["Chapter"] = chapter.ChapterName;
                var user = userService.GetUserByName(User.Identity.Name);
                
                var resultsOfChapter = ViewModelConverter.ConvertQuizToChapterResults(resultService.GetChapterResult(chapter, user));//получает результаты последнего теста, проходимого пользователем.

                if (resultsOfChapter.TestStatus == TestStatus.Passed || resultsOfChapter.TestStatus == TestStatus.Failed)//Если тест вообще был пройден
                {
                    //Сказать что тест уже был пройден! Успешно или неуспешно покажет вьюха
                    return Redirect("/Result/GetChapterResults" + "/" + chapterId);
                }

                if (!CheckIfPreviousTestsArePassed(chapter, user))
                {
                    //Сказать, что невозможно пройти данный тест так как предыдущий не был пройден
                    return View("PreviousTestNotPassed");
                }

                //Иначе если все условия не были выполнены, то проходим тест
                var resultView = TakeQuestionForUser(user, chapter);
                unit.Commit();
                return resultView;//TODO: Надо бы логику переписать, а то не очень-то очевидна
            }

        }

        [Authorize]
        public ActionResult RestartTest(int chapterId)
        {
            using (var unit = unitOfWorkFactory.Create())
            {
                var chapter = databaseService.Chapters.Get(chapterId);
                if (chapter == null)
                {
                    return null;
                }
                var user = userService.GetUserByName(User.Identity.Name);
                if (!quizService.IfThereIsUncompletedTestForUser(user, chapter))
                {
                    var resultView = TakeQuestionForUser(user, chapter);
                    unit.Commit();
                    return resultView;
                }
                else
                {
                    return Redirect("/Test/GetTest?chapterId=" + chapterId);
                }
            }
        }


        private bool CheckIfPreviousTestsArePassed(Chapter chapter, User user)
        {
            var topic = databaseService.Topics.Get(chapter.Topic.Id);
            var previousChapterIndex = topic.Chapters.ToList().IndexOf(chapter) - 1;//Ищем главу, которая предшествует той, по которой пытаемся пройти тест
            if (previousChapterIndex >= 0)//Если глава найдена
            {
                var previousChapter = topic.Chapters.ToList()[previousChapterIndex] ?? null;
                var resultsOfPreviousChapter =
                     ViewModelConverter.ConvertQuizToChapterResults(resultService.GetChapterResult(previousChapter, user));//Смотрим ее результаты
                if (resultsOfPreviousChapter.TestStatus != TestStatus.Passed)//И если она не пройдена, то тест по текущей главе нельзя пройти
                {
                    return false;
                }
            }
            return true;
        }

        

        private ViewResult TakeQuestionForUser(User user, Chapter chapter)
        {
            var question = quizService.FormQuestionForUser(user, chapter);
            if (question == null) return null;
            switch (question.Question.GetQuestionType())
            {
                case QuestionType.open:
                    {
                        var chapterViewModel = ViewModelConverter.ConvertQuestionToOpenViewModel(question);
                        return View("GetTestOpenQuestion", chapterViewModel);
                    }
                case QuestionType.check:
                    {
                        var chapterViewModel = ViewModelConverter.ConvertQuestionToCheckViewModel(question);
                        return View("GetTestCheckbox", chapterViewModel);
                    }
                case QuestionType.radio:
                    {
                        var chapterViewModel = ViewModelConverter.ConvertQuestionToRadioViewModel(question);
                        return View("GetTestRadio", chapterViewModel);
                    }
                default: return null;
            }
        }
        [Authorize]
        public ActionResult AcceptAnswerForOpen(int questionInQuizId, string answerText)
        {
            using (var unit = unitOfWorkFactory.Create())
            {
                quizService.PassAnswerToOpenQuestionInQuiz(questionInQuizId, answerText);
                unit.Commit();
                return RedirectToNextQuestion(quizService.GetChapterIdForQuestionInQuiz(questionInQuizId));
            }
            
        }
        [Authorize]
        public ActionResult AcceptAnswerForRadio(int questionInQuizId, int? answerId)
        {
            using (var unit = unitOfWorkFactory.Create())
            {
                if (answerId != null)
                {
                    quizService.PassAnswerToRadioQuestionInQuiz(questionInQuizId, (int)answerId);
                    unit.Commit();
                }
                return RedirectToNextQuestion(quizService.GetChapterIdForQuestionInQuiz(questionInQuizId));
            }
        }

        [Authorize]
        public ActionResult AcceptAnswerForCheck(int questionInQuizId, int[] answersIds)
        {
           
                using (var unit = unitOfWorkFactory.Create())
                {
                    if (answersIds != null)
                    {
                        quizService.PassAnswerToCheckQuestionInQuiz(questionInQuizId, answersIds);
                        unit.Commit();
                    }
                    return RedirectToNextQuestion(quizService.GetChapterIdForQuestionInQuiz(questionInQuizId));
                }
            }

        private RedirectResult RedirectToNextQuestion(int chapterId)
        {
            return Redirect("/Test/GetTest?chapterId=" + chapterId);
        }

    }
}
